from .metadata import *
import string


@dataclass
class FileRatioProperty:
    blank_line_ratio:float=0.
    comment_ratio:float=0.
    literal_ratio:float=0.
    tab_indent_ratio:float=0.
    new_line_before_open_brance_ratio:float=0.
    on_line_before_open_brance_ratio:float=0.
    func_avg_ratio:float=0.
    word_avg_ratio:float=0.
    white_space_ratio:float=0.

@dataclass
class FileVectorProperty:
    identifier_habit:list=field(default_factory=list)
    digit_habit:list=field(default_factory=list)
    string_habit:list=field(default_factory=list)

@dataclass
class FileProperty:
    ratio_property:FileRatioProperty=FileRatioProperty()
    vector_property:FileVectorProperty=FileVectorProperty()
    
class FilePropertyFactory:
    @staticmethod
    def create_ratio_property(file_info:FileInfo):
        length=file_info.file_length
        line_number=file_info.file_line_number
        
        scalars=file_info.file_features.scalars
        frequencys=file_info.file_features.frequencys
        
        blank_line_ratio=scalars.blank_line_number/line_number
        comment_ratio=scalars.comment_number/length
        literal_ratio=scalars.literal_number/length
        word_avg_ratio=1/(length/max(1,scalars.word_number))
        tab_indent_ratio=scalars.tab_indent_number/length
        new_line_before_open_brance_ratio=scalars.new_line_before_open_brance_number/line_number
        on_line_before_open_brance_ratio=scalars.on_line_before_open_brance_number/line_number
        white_space_ratio=scalars.white_space_number/length
        func_avg_ratio=1/max(1,file_info.file_features.scalars.function_number)
    
        
        return FileRatioProperty(blank_line_ratio=blank_line_ratio,
                               comment_ratio=comment_ratio,
                               literal_ratio=literal_ratio,
                               tab_indent_ratio=tab_indent_ratio,
                               new_line_before_open_brance_ratio=new_line_before_open_brance_ratio,
                               on_line_before_open_brance_ratio=on_line_before_open_brance_ratio,
                               #func_avg_ratio=func_avg_ratio,
                               #word_avg_ratio=word_avg_ratio,
                               #white_space_ratio=white_space_ratio
                               )
    
    @staticmethod
    def create_vector_property(file_info:FileInfo):
        length=file_info.file_length
        line_number=file_info.file_line_number

        word_freq=file_info.file_features.frequencys.word
        
        identifier_habit=[0,0,0,0]
        char_number=0
        for word in word_freq:
            if word.isidentifier():
                char_number+=(len(word)*word_freq[word])
                for c in word:
                    if c in string.digits: identifier_habit[0]+=word_freq[word]
                    elif c in string.ascii_lowercase: identifier_habit[1]+=word_freq[word]
                    elif c in string.ascii_uppercase: identifier_habit[2]+=word_freq[word]
                    elif c in string.punctuation: identifier_habit[3]+=word_freq[word]

        char_number=max(1,char_number)
        identifier_habit=[e/char_number for e in identifier_habit]


        digit_habit=[0,0,0,0]
        char_number=0
        for word in word_freq:
            if word.isdigit():
                #char_number+=(len(word)*word_freq[word])
                for c in word:
                    char_number+=word_freq[word]
                    if c =='0': digit_habit[0]+=word_freq[word]
                    elif c in ['123456789']: digit_habit[1]+=word_freq[word]
                    elif c in string.ascii_lowercase: digit_habit[2]+=word_freq[word]
                    elif c in string.ascii_uppercase: digit_habit[3]+=word_freq[word]
                    else:
                        char_number-=word_freq[word]

        char_number=max(1,char_number)
        digit_habit=[e/char_number for e in digit_habit]

        string_habit=[0,0,0,0]
        char_number=0
        for word in word_freq:
            if not word.isidentifier() and not word.isdigit():
                char_number+=(len(word)*word_freq[word])
                for c in word:
                    if c in string.digits: string_habit[0]+=word_freq[word]
                    elif c in string.ascii_lowercase: string_habit[1]+=word_freq[word]
                    elif c in string.ascii_uppercase: string_habit[2]+=word_freq[word]
                    elif c in string.punctuation: string_habit[3]+=word_freq[word]

        char_number=max(1,char_number)
        string_habit=[e/char_number for e in string_habit]
        
        return FileVectorProperty(string_habit=string_habit,identifier_habit=identifier_habit,digit_habit=digit_habit)
    
    @staticmethod
    def create_property(file_info:FileInfo):
        return FileProperty(FilePropertyFactory.create_ratio_property(file_info),
                            FilePropertyFactory.create_vector_property(file_info))

        